package org.luxor.eshop.payment.service.impl;

import io.seata.rm.tcc.api.BusinessActionContext;
import org.luxor.commons.core.exception.TransactionException;
import org.luxor.commons.redis.plugin.idempotent.service.IdempotentService;
import org.luxor.eshop.payment.entity.PaymentEntity;
import org.luxor.eshop.payment.mapper.PaymentMapper;
import org.luxor.eshop.payment.service.OrderFeign;
import org.luxor.eshop.payment.service.TransferTccAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;

/**
 * TCC 转账交易
 *
 * @author Mr.Yan  @date: 2020/12/8
 */
@Component
public class TransferTccActionImpl implements TransferTccAction {
    private static final Logger logger = LoggerFactory.getLogger(TransferTccActionImpl.class);

    @Resource
    private IdempotentService idempotentService;
    @Resource
    private OrderFeign orderFeign;
    @Resource
    private PaymentMapper paymentMapper;

    @Override
    @Transactional(rollbackFor = TransactionException.class)
    public boolean prepare(BusinessActionContext actionContext, Long billCode, Long orderId,
                           String buyerAccount, String sellerAccount, BigDecimal amounts) {
        // 注册幂等控制器
        idempotentService.register("TransferTccAction", "Transfer-" + actionContext.getXid());

        // 新增交易账单记录
        PaymentEntity entity = new PaymentEntity();
        entity.setPaymentId(billCode);
        entity.setOrderId(orderId);
        entity.setBuyerAccount(buyerAccount);
        entity.setSellerAccount(sellerAccount);
        entity.setAmounts(amounts);
        paymentMapper.insert(entity);


        logger.info("TTC转张交易 - [第一阶段：预留资源(Prepare)],执行成功");
        return true;
    }

    @Override
    @Transactional(rollbackFor = TransactionException.class)
    public boolean commit(BusinessActionContext actionContext) {
        // 防止幂等请求
        boolean checkResult = idempotentService.questionPass("TransferTccAction", "Transfer-" + actionContext.getXid());
        if (checkResult) {
            // 1、修改订单状态为'已支付'
            Object orderId = actionContext.getActionContext().get("orderId");
            if (orderId != null && Long.parseLong(orderId.toString()) != 0) {
                orderFeign.paySuccess(Long.parseLong(orderId.toString())).assertSuccess();
            }

            // 2、交易成功，记录支付完成时间
            Long billCode = Long.valueOf(actionContext.getActionContext().get("billCode").toString());
            PaymentEntity entity = new PaymentEntity();
            entity.setPaymentId(billCode);
            entity.setPayTime(new Date());
            paymentMapper.updateById(entity);

            logger.info("TTC转张交易 - [第二阶段：确认/提交(Commit)],执行成功");
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = TransactionException.class)
    public boolean rollback(BusinessActionContext actionContext) {
        logger.info("TTC转张交易 - [第二阶段：取消/回滚(Rollback)],开始执行...");

        // 解决空回滚&幂等控制
        boolean checkResult = idempotentService.questionPass("TransferTccAction", "Transfer-" + actionContext.getXid());
        if (checkResult) {
            // 1、修改订单状态为'支付失败'
            Object orderId = actionContext.getActionContext().get("orderId");
            if (orderId != null && Long.parseLong(orderId.toString()) != 0) {
                orderFeign.payFailed(Long.parseLong(orderId.toString()));
            }

            // 2、交易失败，记录支付异常时间
            Object billCode = actionContext.getActionContext().get("billCode");
            if (billCode != null && Long.parseLong(billCode.toString()) != 0) {
                paymentMapper.deleteById(Long.parseLong(billCode.toString()));

                logger.info("TTC转张交易 - [第二阶段：取消/回滚(Rollback)],执行成功");
            }
        }
        return true;
    }
}
